using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute


namespace EWF_Install
{
        //=========================================================
    class TokenPrivileges
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public int LowPart;
            public int HighPart;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public int PrivilegeCount;
            public LUID Luid;
            public int Attributes;
        }
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool OpenProcessToken(int ProcessHandle, int DesiredAccess,
        ref int tokenhandle);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern int GetCurrentProcess();

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool LookupPrivilegeValue(string lpsystemname, string lpname,
        [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool AdjustTokenPrivileges(int tokenhandle, int disableprivs,
        [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES Newstate, int bufferlength, int PreivousState, int Returnlength);

        public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        public const int TOKEN_QUERY = 0x00000008;
        public const int SE_PRIVILEGE_ENABLED = 0x00000002;
        public const string SE_RESTORE_NAME = "SeRestorePrivilege";
        public const string SE_BACKUP_NAME = "SeBackupPrivilege";
        //
        public const uint HKEY_CLASSES_ROOT        =0x80000000;
        public const uint HKEY_CURRENT_USER        =0x80000001;
        public const uint HKEY_LOCAL_MACHINE       =0x80000002;
        public const uint HKEY_USERS               =0x80000003;
        public const uint HKEY_PERFORMANCE_DATA    =0x80000004;
        public const uint HKEY_PERFORMANCE_TEXT    =0x80000050;
        public const uint HKEY_PERFORMANCE_NLSTEXT =0x80000060;
        public const uint HKEY_CURRENT_CONFIG      =0x80000005;
        public const uint HKEY_DYN_DATA            =0x80000006;

        public const uint KEY_QUERY_VALUE          =0x0001;
        public const uint KEY_ENUMERATE_SUB_KEYS   =0x0008;
        public const uint KEY_ALL_ACCESS = 0xF003F;

        public const uint REG_NONE                 =0;
        public const uint REG_SZ                   =1;
        public const uint REG_EXPAND_SZ            =2;
        public const uint REG_BINARY               =3;
        public const uint REG_DWORD                =4;
        public const uint REG_DWORD_LITTLE_ENDIAN  =4;
        public const uint REG_DWORD_BIG_ENDIAN     =5;
        public const uint REG_LINK                 =6;
        public const uint REG_MULTI_SZ             =7;

        private const int ERROR_SUCCESS = 0;


        public static bool Adjust()
        {
            int token=0;
            bool retVal = true;

            TOKEN_PRIVILEGES TP = new TOKEN_PRIVILEGES();
            TOKEN_PRIVILEGES TP2 = new TOKEN_PRIVILEGES();
            LUID RestoreLuid = new LUID();
            LUID BackupLuid = new LUID();

            if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token))
            {
                retVal = false;
                Console.WriteLine("OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY)");
            }
            if (!LookupPrivilegeValue(null, SE_RESTORE_NAME, ref RestoreLuid))
            {
                retVal = false;
                Console.WriteLine("LookupPrivilegeValue(SE_RESTORE_NAME)");
            }
            if(!LookupPrivilegeValue(null, SE_BACKUP_NAME, ref BackupLuid))
            {
                retVal = false;
                Console.WriteLine("LookupPrivilegeValue(SE_BACKUP_NAME)");
            }
            TP.PrivilegeCount = 1;
            TP.Attributes = SE_PRIVILEGE_ENABLED;
            TP.Luid = RestoreLuid;
            TP2.PrivilegeCount = 1;
            TP2.Attributes = SE_PRIVILEGE_ENABLED;
            TP2.Luid = BackupLuid;

            if (!AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0))
            {
                retVal = false;
                Console.WriteLine("AdjustTokenPrivileges(TP)");
            }
            if (!AdjustTokenPrivileges(token, 0, ref TP2, 1024, 0, 0))
            {
                retVal = false;
                Console.WriteLine("AdjustTokenPrivileges(TP2)");
            }
            //
            return retVal;
        }
        //
        }//class
}//namespace
